namespace MoreLinq.Collections;

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

/// <summary>
/// A minimal <see cref="System.Collections.Generic.Dictionary{TKey,TValue}"/> wrapper that
/// allows a null key.
/// </summary>

// Add members if and when needed to keep coverage.

sealed class Dictionary<TKey, TValue>
{
    readonly System.Collections.Generic.Dictionary<ValueTuple<TKey>, TValue> dict;

    public Dictionary(IEqualityComparer<TKey> comparer)
    {
            var keyComparer = ReferenceEquals(comparer, EqualityComparer<TKey>.Default)
                ? null
                : new ValueTupleItemComparer<TKey>(comparer);
            this.dict = new System.Collections.Generic.Dictionary<ValueTuple<TKey>, TValue>(keyComparer);
        }

    public TValue this[TKey key]
    {
        get => this.dict[ValueTuple.Create(key)];
        set => this.dict[ValueTuple.Create(key)] = value;
    }

    public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) =>
        this.dict.TryGetValue(ValueTuple.Create(key), out value);

    sealed class ValueTupleItemComparer<T>(IEqualityComparer<T> comparer) :
        IEqualityComparer<ValueTuple<T>>
    {
        public bool Equals(ValueTuple<T> x, ValueTuple<T> y) => comparer.Equals(x.Item1, y.Item1);
        public int GetHashCode(ValueTuple<T> obj) => obj.Item1 is { } some ? comparer.GetHashCode(some) : 0;
    }
}
